package com.zkyt.lib_msdk_ext.component

import android.os.BatteryManager
import com.geoai.mavlink.geoainet.battery.info.BatteryStateInfo
import com.geoai.mavlink.geoainet.battery.interfaces.IBatteryManager
import com.zkyt.lib_msdk_ext.common.CallbackWithRxHandler
import com.zkyt.lib_msdk_ext.common.CompletionCbRxHandler
import com.zkyt.lib_msdk_ext.common.SDKExtUtil
import com.zkyt.lib_msdk_ext.component.CrestManagerExt.autoGetProcessor
import com.zkyt.lib_msdk_ext.log.SDKExtLog
import io.reactivex.Completable
import io.reactivex.subjects.BehaviorSubject
import io.reactivex.Observable
import io.reactivex.Single
import java.util.*

/**
 * Created by chenyu on 2024/1/18
 * Description:
 */
object BatteryManagerExt: AbsSDKExt<IBatteryManager>(), IRemovableComp {
    private val isConnectSubject = BehaviorSubject.createDefault(false)
    private var batteryManager: IBatteryManager? = null

    private val orgBatteryStateSubject =
        BehaviorSubject.createDefault<Optional<List<BatteryStateInfo>>>(Optional.ofNullable(null))

    override fun init(originManager: IBatteryManager) {
        batteryManager = originManager

        batteryManager?.setBatteryStateListener {
            orgBatteryStateSubject.onNext(Optional.of(it))
        }
        isConnectSubject.onNext(true)
        SDKExtLog.i("BatteryManagerExt", "init")
    }

    override fun isConnected(): Boolean {
        return isConnectSubject.value!!
    }

    override fun getConnectedObservable(): Observable<Boolean> {
        return isConnectSubject.hide()
    }

    override fun destroy() {
        super.destroy()
        SDKExtLog.i("BatteryManagerExt", "destroy")
        isConnectSubject.onNext(false)
        batteryManager?.setBatteryStateListener(null)
        orgBatteryStateSubject.onNext(Optional.ofNullable(null))

        batteryManager = null
    }

    override fun getOriginManager(): IBatteryManager? {
        return batteryManager
    }

    fun getBatteryStateInfoObservable(): Observable<Optional<List<BatteryStateInfo>>> {
        return orgBatteryStateSubject.hide()
    }

    fun setBatteryCriticalThresholdRx(level: Float): Completable {
        return Completable.create {
                emitter ->
            batteryManager?.setBatteryCriticalThreshold(level
            ) { geoaiError ->
                SDKExtUtil.handleError(emitter, geoaiError)
            }
        }
    }

    fun getBatteryCriticalThresholdRx(): Single<Float> {
        return Single.create { emitter ->
            batteryManager?.getBatteryCriticalThreshold(CallbackWithRxHandler(emitter))
        }
    }

    fun getBatteryCriticalThresholdObservable(): Observable<Optional<Float>> {
        val curMethod = object : Any() {}.javaClass.enclosingMethod
        return autoGetProcessor.getAutoGetSubject(curMethod, this::getBatteryCriticalThresholdRx , 2000)
    }

    fun setBatteryEmergencyThresholdRx(level: Float): Completable {
        return Completable.create {
                emitter ->
            batteryManager?.setBatteryEmergencyThreshold(level, CompletionCbRxHandler(emitter))
        }
    }

    fun getBatteryEmergencyThresholdRx(): Single<Float> {
        return Single.create { emitter ->
            batteryManager?.getBatteryEmergencyThreshold(CallbackWithRxHandler(emitter))
        }
    }

    fun getBatteryEmergencyThresholdObservable(): Observable<Optional<Float>> {
        val curMethod = object : Any() {}.javaClass.enclosingMethod
        return autoGetProcessor.getAutoGetSubject(curMethod, this::getBatteryEmergencyThresholdRx , 2000)
    }

    fun getRcBatteryPercentRx(manager: BatteryManager): Single<Int> {
        return Single.create { emitter ->
            val currentLevel = manager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
            emitter.onSuccess(currentLevel)
        }
    }

    fun getRcBatteryPercentObservable(manager: BatteryManager): Observable<Optional<Int>> {
        val curMethod = object : Any() {}.javaClass.enclosingMethod
        return autoGetProcessor.getAutoGetSubject(curMethod, { this.getRcBatteryPercentRx(manager) }, 2000)
    }

    fun setSmartReturnToHomeEnabledRx(enable: Boolean): Completable {
        return Completable.create {
                emitter ->
            batteryManager?.setSmartReturnToHomeEnabled(enable, CompletionCbRxHandler(emitter))
        }
    }

    fun getSmartReturnToHomeEnabledRx(): Single<Boolean> {
        return Single.create { emitter ->
            batteryManager?.getSmartReturnToHomeEnabled(CallbackWithRxHandler(emitter))
        }
    }

    fun getSmartReturnToHomeEnabledObservable(): Observable<Optional<Boolean>> {
        val curMethod = object : Any() {}.javaClass.enclosingMethod
        return autoGetProcessor.getAutoGetSubject(curMethod, this::getSmartReturnToHomeEnabledRx, 2000)
    }
}